package SimpleLACore

import chisel3._
import chisel3.util._


class SimpleLACoreTopAXI extends Module{
  val io = IO(new Bundle {
    val ipi = Input(Bool())
    val interrupt = Input(UInt(8.W))
    val diff = Output(new Difftest)
    val axi = new AXI4Bundle
  })
  val core = Module(new SimpleLACore)

  val iCache = Module(new SimpleICacheAXI(0))
  val dCache = Module(new SimpleCacheAXI(1))

  val arArb = Module(new Arbiter(new AXI4BundleAR, 2))
  val awArb = Module(new Arbiter(new AXI4BundleAW, 2))
  val wArb = Module(new Arbiter(new AXI4BundleW, 2))

  val arQueue = Queue(arArb.io.out, 1, pipe = true, flow = true)
  val awQueue = Queue(awArb.io.out, 1, pipe = true, flow = true)
  val wQueue = Queue(wArb.io.out, 1, pipe = true, flow = true)

  core.io.ipi := io.ipi
  core.io.interrupt := io.interrupt
  core.io.inst <> iCache.io.core
  core.io.data <> dCache.io.core

  io.diff <> core.io.diff

  io.axi.ar <> arQueue
  io.axi.aw <> awQueue
  io.axi.w <> wQueue
  io.axi.r.ready := false.B
  io.axi.b.ready := false.B
  
  Seq((iCache.io.mem, iCache.id), (dCache.io.mem, dCache.id)).foreach{ case (axi, id) =>
    arArb.io.in(id) <> axi.ar
    awArb.io.in(id) <> axi.aw
    wArb.io.in(id) <> axi.w
    when(io.axi.r.bits.id === id.U) {
      axi.r <> io.axi.r
    }.otherwise {
      axi.r.valid := false.B
      axi.r.bits := DontCare
    }
    when(io.axi.b.bits.id === id.U) {
      axi.b <> io.axi.b
    }.otherwise {
      axi.b.valid := false.B
      axi.b.bits := DontCare
    }
  }
}
